<template>
  <div class="app-container">
    <!-- 顶部状态栏 -->
    <el-alert type="info" :closable="false" class="mb-4">
      <template #default>
        <el-row :gutter="20" align="middle">
          <el-col :span="24">
            <el-space>
              <span>WebSocket:</span>
              <el-tag :type="wsConnected ? 'success' : 'danger'">
                {{ wsConnected ? '已连接' : '未连接' }}
              </el-tag>
              <el-divider direction="vertical" />
              <span>在线: <el-tag type="success">{{ onlineCount }}</el-tag></span>
              <span>离线: <el-tag type="info">{{ offlineCount }}</el-tag></span>
              <span>已登录: <el-tag type="warning">{{ loggedInCount }}</el-tag></span>
            </el-space>
          </el-col>
        </el-row>
      </template>
    </el-alert>

    <!-- 搜索表单 -->
    <el-form
      :model="queryParams"
      ref="queryRef"
      v-show="showSearch"
      :inline="true"
      label-width="110px"
      class="mb-4"
    >
      <el-form-item label="客户端名称" prop="client_name">
        <el-input
          v-model="queryParams.client_name"
          placeholder="请输入客户端名称"
          clearable
          style="width: 240px"
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="IP地址" prop="ip_address">
        <el-input
          v-model="queryParams.ip_address"
          placeholder="请输入IP地址"
          clearable
          style="width: 200px"
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="在线状态" prop="online_status">
        <el-select
          v-model="queryParams.online_status"
          placeholder="请选择"
          clearable
          style="width: 120px"
        >
          <el-option label="在线" value="online" />
          <el-option label="离线" value="offline" />
        </el-select>
      </el-form-item>
      <el-form-item label="登录状态" prop="login_status">
        <el-select
          v-model="queryParams.login_status"
          placeholder="请选择"
          clearable
          style="width: 120px"
        >
          <el-option label="已登录" value="logged_in" />
          <el-option label="未登录" value="not_logged_in" />
          <el-option label="登录中" value="logging_in" />
          <el-option label="登录失败" value="login_error" />
        </el-select>
      </el-form-item>
      <el-form-item label="浏览器状态" prop="browser_status">
        <el-select
          v-model="queryParams.browser_status"
          placeholder="请选择"
          clearable
          style="width: 120px"
        >
          <el-option label="已启动" value="running" />
          <el-option label="已关闭" value="stopped" />
          <el-option label="启动中" value="starting" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 工具栏 -->
    <el-row :gutter="10" class="mb-4" justify="space-between">
      <el-col :span="20">
        <el-button type="primary" plain icon="Refresh" @click="loadClientList">刷新</el-button>
        <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
        <el-button 
          v-if="isAdmin"
          type="success" 
          plain 
          icon="User" 
          @click="handleBatchAssign"
          :disabled="selectedClients.length === 0"
        >
          批量分配
        </el-button>
      </el-col>
      <el-col :span="4" style="text-align: right;">
        <el-button circle :icon="showSearch ? 'ArrowUp' : 'ArrowDown'" @click="showSearch = !showSearch" title="显示/隐藏搜索" />
      </el-col>
    </el-row>

    <!-- 客户端列表表格 -->
    <el-table
      v-loading="loading"
      :data="filteredClientList"
      border
      @selection-change="handleSelectionChange"
      :row-class-name="getRowClassName"
    >
      <el-table-column type="selection" width="55" align="center" />
      
      <!-- 第1列：主机名（移到第一列，固定列） -->
      <el-table-column label="主机名称" align="center" width="130" fixed="left" sortable prop="server_host_name" :sort-method="naturalSortByHostName">
        <template #default="{ row }">
          <div style="font-size: 14px; font-weight: 600; color: #67C23A;">
            {{ row.server_host_name || '-' }}
          </div>
        </template>
      </el-table-column>
      
      <!-- 第2列：IP|状态 -->
      <el-table-column label="IP | 状态" align="center" width="160" sortable prop="ip_address">
        <template #default="{ row }">
          <div style="font-size: 12px; line-height: 1.4;">
            <div style="color: #606266; font-weight: 500; margin-bottom: 4px;">
              {{ row.ip_address || '-' }}
            </div>
            <el-tag :type="row.online_status === 'online' ? 'success' : 'info'" size="small">
              {{ row.online_status === 'online' ? '在线' : '离线' }}
            </el-tag>
          </div>
        </template>
      </el-table-column>

      <!-- 第3列：计算机名|ID -->
      <el-table-column label="计算机名 | ID" align="center" min-width="180" sortable prop="hostname">
        <template #default="{ row }">
          <div style="font-size: 12px; line-height: 1.3;">
            <div style="font-weight: 600; color: #409EFF; margin-bottom: 2px;">
              {{ row.hostname || 'unknown' }}
            </div>
            <div style="color: #909399; font-size: 11px;">
              {{ row.client_id }}
            </div>
          </div>
        </template>
      </el-table-column>
      
      
      <!-- 第4列：账号 -->
      <el-table-column label="账号" align="center" min-width="150" sortable prop="account">
        <template #default="{ row }">
          <div v-if="row.account" style="line-height: 1.4;">
            <!-- 昵称 - 粗体 -->
            <div v-if="row.account_nickname" style="font-weight: 600; color: #303133; margin-bottom: 2px;">
              {{ row.account_nickname }}
            </div>
            <!-- ID - 小号灰色 -->
            <div style="font-size: 12px; color: #909399;">
              {{ row.account }}
            </div>
          </div>
          <span v-else style="color: #C0C4CC;">未登录</span>
        </template>
      </el-table-column>
      
      <!-- 第5列：账号类型 -->
      <el-table-column label="账号类型" align="center" width="100" sortable prop="client_type">
        <template #default="{ row }">
          <el-tag :type="getClientTypeTagType(row.client_type)" size="small">
            {{ getClientTypeLabel(row.client_type) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="浏览器" prop="browser_status" align="center" width="140" sortable>
        <template #default="{ row }">
          <el-tag :type="getBrowserStatusType(row.browser_status)">
            {{ row.browser_status_cn || row.browser_status }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="登录状态" prop="login_status" align="center" width="110" sortable>
        <template #default="{ row }">
          <el-tag :type="getLoginStatusType(row.login_status)">
            {{ row.login_status_cn || row.login_status }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="工作状态" prop="work_status" align="center" width="100" sortable>
        <template #default="{ row }">
          <el-tag 
            :type="getWorkStatusType(row.work_status)" 
            effect="plain"
            :style="row.work_status === 'banned' ? { color: '#f56c6c', borderColor: '#f56c6c' } : {}"
          >
            {{ row.work_status_cn || row.work_status }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="默认地址" align="center" width="180" sortable prop="default_address_id">
        <template #default="{ row }">
          <div v-if="row.default_address_id" style="line-height: 1.4;">
            <!-- 上面显示"已选择"标签 -->
            <el-tag type="success" size="small" style="margin-bottom: 6px; display: block; width: fit-content; margin-left: auto; margin-right: auto;">
              已选择
            </el-tag>
            <!-- 下面显示"点击查看详情"按钮 -->
            <el-button
              link
              type="primary"
              size="small"
              style="font-size: 12px; padding: 0;"
              @click="handleViewDetail(row)"
            >
              点击查看详情
            </el-button>
          </div>
          <span v-else style="color: #C0C4CC;">-</span>
        </template>
      </el-table-column>
      <el-table-column label="分配用户" align="center" min-width="150" sortable prop="assigned_user_name">
        <template #default="{ row }">
          <div v-if="row.assigned_user_name" style="line-height: 1.4;">
            <el-tag type="success" size="small">
              {{ row.assigned_user_name }}
            </el-tag>
          </div>
          <span v-else style="color: #909399; font-size: 12px;">管理员管理</span>
        </template>
      </el-table-column>
      <el-table-column label="备注" prop="remark" align="center" min-width="120" show-overflow-tooltip sortable />
      <el-table-column label="最后心跳" prop="last_heartbeat" align="center" width="170" sortable>
        <template #default="{ row }">
          {{ formatDate(row.last_heartbeat) }}
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="400" fixed="right">
        <template #default="{ row }">
          <!-- 第一行按钮 -->
          <div style="margin-bottom: 4px;">
            <el-button
              link
              type="info"
              icon="Document"
              @click="handleViewDetail(row)"
            >
              查看
            </el-button>
            <el-button
              link
              type="primary"
              icon="Edit"
              @click="handleEdit(row)"
            >
              编辑
            </el-button>
            <el-button
              link
              type="primary"
              icon="VideoPlay"
              @click="handleStart(row)"
              :disabled="row.online_status !== 'online' || row.browser_status === 'running'"
            >
              启动
            </el-button>
            <el-button
              link
              type="danger"
              icon="VideoPause"
              @click="handleStop(row)"
              :disabled="row.online_status !== 'online' || row.browser_status !== 'running'"
            >
              关闭
            </el-button>
            <el-button
              link
              type="warning"
              icon="RefreshLeft"
              @click="handleReset(row)"
              :disabled="row.online_status !== 'online'"
            >
              重置
            </el-button>
          </div>
          <!-- 第二行按钮 -->
          <div>
            <el-button
              link
              type="success"
              icon="Picture"
              @click="handleQRLogin(row)"
              :disabled="row.online_status !== 'online' || row.login_status === 'logged_in'"
            >
              二维码登录
            </el-button>
            <el-button
              link
              type="warning"
              icon="Message"
              @click="handleSMSLogin(row)"
              :disabled="row.online_status !== 'online' || row.login_status === 'logged_in'"
            >
              手机号登录
            </el-button>
            <el-button
              link
              type="info"
              icon="Location"
              @click="handleSelectAddress(row)"
              :disabled="row.online_status !== 'online' || row.login_status !== 'logged_in'"
            >
              选择地址
            </el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>

    
    <!-- 地址选择弹窗 - 卡片式布局 -->
    <el-dialog
      v-model="addressDialogVisible"
      title="选择收货地址"
      width="1100px"
      @close="handleAddressDialogClose"
    >
      <div v-loading="addressLoading" style="min-height: 200px">
        <el-alert
          v-if="addressList.length === 0 && !addressLoading"
          title="暂无收货地址"
          type="info"
          description="请先在闲鱼APP中添加收货地址"
          :closable="false"
          style="margin-bottom: 20px"
        />
        
          <!-- 卡片网格布局（3列） -->
          <div v-if="addressList.length > 0" class="address-grid">
            <div
              v-for="address in addressList"
              :key="address.id"
              class="address-card"
              :class="{ 
                'address-card-selected': selectedAddressId === address.id,
                'address-card-default': address.isDefault
              }"
              @click="selectedAddressId = address.id"
            >
              <!-- 标签区域（右上角） -->
              <div class="address-badges">
                <!-- 默认地址标签（闲鱼的默认地址） -->
              <div v-if="address.isDefault" class="address-default-badge">
                  默认地址（闲鱼）
              </div>
                <!-- 当前选中标签（后台选中的地址，显示在右上角，如果有默认地址则显示在下方） -->
              <div v-if="selectedAddressId === address.id" class="address-selected-badge">
                  已选择
                </div>
              </div>
              
              <!-- 顶部：省/市/区/街道 -->
              <div class="address-top">
                {{ address.fullAddress }}
              </div>
              
              <!-- 中间：详细地址（粗体） -->
              <div class="address-middle">
                {{ address.addressDetail || address.detailAddress }}
              </div>
              
              <!-- 底部：姓名 + 手机号 -->
              <div class="address-bottom">
                <span class="address-name">{{ address.name }}</span>
                <span class="address-phone">{{ address.phone }}</span>
              </div>
              
              <!-- 选中图标（右下角） -->
              <div v-if="selectedAddressId === address.id" class="address-check-icon">
                <el-icon :size="24" color="#67C23A">
                  <SuccessFilled />
                </el-icon>
              </div>
            </div>
          </div>
      </div>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="addressDialogVisible = false">取消</el-button>
          <el-button
            type="primary"
            @click="handleConfirmAddress"
            :disabled="!selectedAddressId || addressLoading"
          >
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 二维码登录弹窗 -->
    <el-dialog
      v-model="qrLoginVisible"
      title="二维码登录"
      width="400px"
      :close-on-click-modal="false"
      @close="stopQRCountdown"
    >
      <!-- ✅ 醒目的提示信息 -->
      <el-alert
        type="warning"
        :closable="false"
        show-icon
        style="margin-bottom: 20px;"
      >
        <template #title>
          <span style="font-size: 13px; color: #606266">
            ⚠️ 请先退出其他网页上的闲鱼账号，避免登录冲突
          </span>
        </template>
      </el-alert>
      
      <div style="text-align: center">
        <el-image
          v-if="qrCodeData"
          :src="qrCodeData"
          style="width: 300px; height: 300px"
          fit="contain"
        />
        <div v-else style="width: 300px; height: 300px; display: flex; align-items: center; justify-content: center; background: #f5f5f5">
          <el-icon :size="60" color="#909399"><Loading /></el-icon>
        </div>
        <div style="margin-top: 20px; color: #606266">
          <!-- 状态文本 -->
          <p style="margin-bottom: 10px; font-size: 15px">
            {{ qrStatusText }}
          </p>
          
          <!-- 倒计时 -->
          <p v-if="qrCountdown > 0" style="margin-bottom: 10px">
            <span style="color: #409eff; font-size: 14px">
              剩余时间：{{ formatCountdown(qrCountdown) }}
            </span>
          </p>
          <p v-else style="color: #f56c6c; font-size: 16px; font-weight: bold; margin-bottom: 10px">
            ⚠️ 二维码已过期
          </p>
          
          <!-- 刷新按钮 -->
          <el-button type="primary" @click="handleRefreshQRCode" :loading="qrLoading">
            {{ qrCountdown > 0 ? '刷新二维码' : '重新获取' }}
          </el-button>
        </div>
      </div>
    </el-dialog>

    <!-- 手机号登录弹窗 -->
    <el-dialog
      v-model="smsLoginVisible"
      title="手机号登录"
      width="400px"
      :close-on-click-modal="false"
    >
      <!-- ✅ 醒目的提示信息 -->
      <el-alert
        type="warning"
        :closable="false"
        show-icon
        style="margin-bottom: 20px;"
      >
        <template #title>
          <span style="font-size: 13px; color: #606266">
            ⚠️ 请先退出其他网页上的闲鱼账号，避免登录冲突
          </span>
        </template>
      </el-alert>
      
      <el-form :model="smsForm" label-width="80px">
        <el-form-item label="手机号">
          <el-input v-model="smsForm.phone" placeholder="请输入手机号" />
        </el-form-item>
        <el-form-item label="验证码">
          <el-input v-model="smsForm.code" placeholder="请输入验证码">
            <template #append>
              <el-button @click="handleSendSMS" :disabled="smsCooldown > 0">
                {{ smsCooldown > 0 ? `${smsCooldown}秒后重试` : '获取验证码' }}
              </el-button>
            </template>
          </el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="smsLoginVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSMSSubmit">登录</el-button>
      </template>
    </el-dialog>

    <!-- Agent分配对话框 -->
    <el-dialog v-model="assignDialogVisible" title="分配Agent" width="600px">
      <el-form :model="assignForm" label-width="100px">
        <el-form-item label="选中Agent">
          <div style="max-height: 120px; overflow-y: auto;">
            <el-tag v-for="client in selectedClients" :key="client.id" style="margin: 4px;" type="primary">
              {{ client.server_host_name || client.client_name }}
            </el-tag>
          </div>
        </el-form-item>
        <el-form-item label="分配给用户">
          <el-select 
            v-model="assignForm.user_id" 
            filterable
            clearable
            placeholder="请选择用户（不选表示回归管理员）" 
            style="width: 100%;"
          >
            <el-option
              v-for="user in userList"
              :key="user.userId"
              :label="`${user.nickName || user.userName} (${user.userName})`"
              :value="user.userId"
            />
          </el-select>
          <div style="margin-top: 8px; font-size: 12px; color: #909399;">
            提示：不选择任何用户，则将Agent回归管理员管理（一个Agent只能分配给一个用户）
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="assignDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitAssign" :loading="assignLoading">确定</el-button>
      </template>
    </el-dialog>

    <!-- 主机信息详情弹窗 -->
    <el-dialog
      v-model="detailDialogVisible"
      title="主机详细信息"
      width="900px"
      :close-on-click-modal="false"
    >
      <el-descriptions :column="2" border>
        <el-descriptions-item label="主机名" label-class-name="detail-label">
          <span style="font-weight: 600; color: #409EFF;">{{ detailData.hostname || 'unknown' }}</span>
        </el-descriptions-item>
        <el-descriptions-item label="客户端ID" label-class-name="detail-label">
          <span style="font-size: 12px; color: #909399;">{{ detailData.client_id }}</span>
        </el-descriptions-item>
        <el-descriptions-item label="IP地址" label-class-name="detail-label">
          {{ detailData.ip_address || '-' }}
        </el-descriptions-item>
        <el-descriptions-item label="在线状态" label-class-name="detail-label">
          <el-tag :type="detailData.online_status === 'online' ? 'success' : 'info'" size="small">
            {{ detailData.online_status === 'online' ? '在线' : '离线' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="账号昵称" label-class-name="detail-label">
          <span style="font-weight: 600;">{{ detailData.account_nickname || '-' }}</span>
        </el-descriptions-item>
        <el-descriptions-item label="账号ID" label-class-name="detail-label">
          {{ detailData.account || '-' }}
        </el-descriptions-item>
        <el-descriptions-item label="账号类型" label-class-name="detail-label">
          <el-tag :type="getClientTypeTagType(detailData.client_type)" size="small">
            {{ getClientTypeLabel(detailData.client_type) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="浏览器状态" label-class-name="detail-label">
          <el-tag :type="getBrowserStatusType(detailData.browser_status)" size="small">
            {{ detailData.browser_status_cn || detailData.browser_status }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="登录状态" label-class-name="detail-label">
          <el-tag :type="getLoginStatusType(detailData.login_status)" size="small">
            {{ detailData.login_status_cn || detailData.login_status }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="工作状态" label-class-name="detail-label">
          <el-tag :type="getWorkStatusType(detailData.work_status)" size="small" effect="plain">
            {{ detailData.work_status_cn || detailData.work_status }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="默认地址" label-class-name="detail-label" :span="2">
          <template #default>
            <div v-if="detailData.default_address_id">
              <!-- 如果有详细地址信息，直接显示地址 -->
              <template v-if="addressDisplayInfo">
                <div style="font-size: 13px; color: #606266; line-height: 1.8;">
                  <!-- 第一行：姓名 -->
                  <div v-if="addressDisplayInfo.name" style="margin-bottom: 4px; font-weight: 500;">
                    {{ addressDisplayInfo.name }}
                  </div>
                  <!-- 第二行：地址（支持自动换行） -->
                  <div v-if="addressDisplayInfo.address" style="color: #909399; word-wrap: break-word; word-break: break-all;">
                    {{ addressDisplayInfo.address }}
                  </div>
                </div>
              </template>
              <!-- 如果没有地址详细信息，显示"已选择"标签和提示 -->
              <div v-else>
                <el-tag type="success" size="small" style="margin-bottom: 8px; display: block; width: fit-content;">
                  已选择
                </el-tag>
                <div style="color: #909399; font-size: 12px;">
                  地址ID: {{ detailData.default_address_id }}<br/>
                  <span style="color: #C0C4CC; font-size: 11px;">（详细信息需通过"选择地址"功能获取）</span>
                </div>
              </div>
            </div>
            <span v-else style="color: #C0C4CC;">未设置</span>
          </template>
        </el-descriptions-item>
        <el-descriptions-item label="最后心跳" label-class-name="detail-label" :span="2">
          {{ formatDate(detailData.last_heartbeat) }}
        </el-descriptions-item>
        <el-descriptions-item label="备注" label-class-name="detail-label" :span="2">
          <div style="white-space: pre-wrap; max-height: 150px; overflow-y: auto;">
            {{ detailData.remark || '-' }}
          </div>
        </el-descriptions-item>
        <el-descriptions-item label="Cookie信息" label-class-name="detail-label" :span="2">
          <div v-if="detailData.cookies" style="width: 100%; max-width: 100%; overflow: hidden;">
            <el-collapse style="width: 100%;">
              <el-collapse-item name="cookie" style="width: 100%;">
                <template #title>
                  <span style="font-size: 13px; color: #606266;">
                    点击展开查看Cookie详情
                    <el-tag size="small" style="margin-left: 8px;" type="info">
                      {{ getCookieCount(detailData.cookies) }} 个Cookie
                    </el-tag>
                  </span>
                </template>
                <div style="background: #f5f7fa; padding: 12px; border-radius: 4px; max-height: 400px; overflow-y: auto; overflow-x: hidden; width: 100%; max-width: 100%; box-sizing: border-box;">
                  <pre style="margin: 0; font-size: 11px; font-family: 'Consolas', 'Monaco', monospace; white-space: pre-wrap; word-wrap: break-word; overflow-wrap: break-word; word-break: break-all; color: #303133; line-height: 1.6; width: 100%; max-width: 100%; box-sizing: border-box;">{{ formatCookie(detailData.cookies) }}</pre>
          </div>
              </el-collapse-item>
            </el-collapse>
            <!-- 显示关键Cookie信息（折叠状态下也能看到） -->
            <div style="margin-top: 8px; font-size: 12px; color: #909399;">
              <div v-if="getKeyCookieInfo(detailData.cookies)" style="line-height: 1.8;">
                <div v-for="(value, key) in getKeyCookieInfo(detailData.cookies)" :key="key" style="display: flex; align-items: center; margin-bottom: 4px;">
                  <span style="font-weight: 500; color: #606266; min-width: 100px;">{{ key }}:</span>
                  <span style="color: #303133; word-break: break-all;">{{ value }}</span>
                </div>
              </div>
            </div>
          </div>
          <span v-else style="color: #C0C4CC;">暂无Cookie（客户端未上报Cookie数据）</span>
        </el-descriptions-item>
      </el-descriptions>
      <template #footer>
        <el-button @click="detailDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>

    <!-- 编辑Agent弹窗 -->
    <el-dialog
      v-model="editDialogVisible"
      title="编辑Agent配置"
      width="500px"
      :close-on-click-modal="false"
    >
      <el-form :model="editForm" label-width="90px">
        <el-form-item label="账号类型">
          <el-select v-model="editForm.client_type" placeholder="请选择账号类型" style="width: 100%;">
            <el-option label="搜索" value="search" />
            <el-option label="下单" value="order" />
            <el-option label="备用" value="standby" />
          </el-select>
          <div style="color: #909399; font-size: 12px; margin-top: 5px;">
            备用账号不参与自动任务分配
          </div>
        </el-form-item>
        <el-form-item label="备注">
          <el-input
            v-model="editForm.remark"
            type="textarea"
            :rows="3"
            placeholder="请输入备注信息，如账号用途、注意事项等"
            maxlength="500"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="editDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSaveEdit">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Loading, Setting, ArrowUp, ArrowDown, SuccessFilled, Edit } from '@element-plus/icons-vue'
import { useAgentStore } from '@/store/modules/agent'
import useUserStore from '@/store/modules/user'
import { websocketManager } from '@/utils/websocket'
import { getAgentClientList, updateClient, updateClientRemark, assignAgents } from '@/api/agent'
import { listUser } from '@/api/system/user'

// ==================== Store ====================
const agentStore = useAgentStore()

// ==================== Reactive Data ====================
const loading = ref(false)
const showSearch = ref(true)
const clientList = ref([])
const selectedClients = ref([])

// WebSocket状态
const wsConnected = ref(false)
const wsStatus = computed(() => wsConnected.value ? '已连接' : '未连接')

// 统计数据
const onlineCount = computed(() => (clientList.value || []).filter(c => c?.online_status === 'online').length)
const offlineCount = computed(() => (clientList.value || []).filter(c => c?.online_status === 'offline').length)
const loggedInCount = computed(() => (clientList.value || []).filter(c => c?.login_status === 'logged_in').length)

// 查询参数
// ⚠️ 注意：queryParams 使用 reactive，不需要 .value 访问
// 对比：clientList 使用 ref，需要 .value 访问（如：clientList.value）
const queryParams = reactive({
  client_name: '',
  ip_address: '',
  online_status: '', // 为空时不过滤，返回所有客户端（包括离线）
  login_status: '',
  browser_status: ''
})

// 过滤后的客户端列表
const filteredClientList = computed(() => {
  // 先过滤掉无效项
  let list = (clientList.value || []).filter(c => c != null && typeof c === 'object')

  if (queryParams.client_name) {
    list = list.filter(c => c?.client_name && c.client_name.includes(queryParams.client_name))
  }
  if (queryParams.ip_address) {
    list = list.filter(c => c?.ip_address && c.ip_address.includes(queryParams.ip_address))
  }
  if (queryParams.online_status) {
    list = list.filter(c => c?.online_status === queryParams.online_status)
  }
  if (queryParams.login_status) {
    list = list.filter(c => c?.login_status === queryParams.login_status)
  }
  if (queryParams.browser_status) {
    list = list.filter(c => c?.browser_status === queryParams.browser_status)
  }

  return list
})

// 地址选择
const addressDialogVisible = ref(false)
const addressLoading = ref(false)
const addressList = ref([])
const selectedAddressId = ref(null)
const currentAddressClient = ref(null) // 当前选择地址的客户端

// 二维码登录
const qrLoginVisible = ref(false)
const qrCodeData = ref('')
const qrLoading = ref(false)
const currentQRClient = ref(null)
const qrExpireTime = ref(null) // 二维码过期时间（10分钟）
const qrCountdown = ref(600) // 倒计时秒数
const qrCountdownTimer = ref(null) // 倒计时定时器
const qrStatusText = ref('请使用闲鱼APP扫描二维码') // 二维码状态文本

// 手机号登录
const smsLoginVisible = ref(false)
const smsForm = reactive({
  phone: '',
  code: ''
})
const smsCooldown = ref(0)
const currentSMSClient = ref(null)

// 编辑Agent
// ==================== 详情弹窗 ====================
const detailDialogVisible = ref(false)
const detailData = reactive({
  client_id: '',
  hostname: '',
  ip_address: '',
  online_status: '',
  account: '',
  account_nickname: '',
  client_type: '',
  browser_status: '',
  browser_status_cn: '',  // 🔥 中文状态
  login_status: '',
  login_status_cn: '',    // 🔥 中文状态
  work_status: '',
  work_status_cn: '',     // 🔥 中文状态
  default_address_id: '',
  default_address_info: null,  // 保存地址详细信息（用于显示完整地址）
  last_heartbeat: '',
  remark: '',
  cookies: null
})

// ✅ 计算属性：地址显示信息（避免模板中重复调用函数）
const addressDisplayInfo = computed(() => {
  return getAddressDisplayInfo(detailData)
})

// ==================== 编辑弹窗 ====================
const editDialogVisible = ref(false)
const editForm = reactive({
  id: null,
  client_type: '',
  remark: ''
})
const currentEditClient = ref(null)

// ==================== Agent分配功能 ====================
const isAdmin = ref(false) // 是否是管理员
const assignDialogVisible = ref(false)
const assignLoading = ref(false)
const userList = ref([])
const assignForm = reactive({
  user_id: null  // ✅ 改为单个用户ID（1对1分配）
})

// Refs
const queryRef = ref(null)

// ==================== Lifecycle ====================
onMounted(async () => {
  // 注册WebSocket消息处理器（WebSocket已在登录时全局初始化）
  websocketManager.on(handleWebSocketMessage)
  
  // 检查WebSocket连接状态
  if (websocketManager.isConnected()) {
    wsConnected.value = true
  } else {
    wsConnected.value = false
  }
  
  // ✅ 优先从HTTP API获取完整客户端列表（包括离线）
  await loadClientListFromAPI()
  
  // ✅ 检查当前用户是否是管理员
  checkIsAdmin()
  
  // WebSocket用于实时更新状态，不再用于初始加载
  console.log('[ClientList] 页面已挂载，已从API加载完整客户端列表')
})

onUnmounted(() => {
  // 移除消息处理器（但不断开WebSocket连接）
  websocketManager.off(handleWebSocketMessage)
  console.log('[ClientList] 页面已卸载，WebSocket消息处理器已移除')
  
  // 清理倒计时定时器
  stopQRCountdown()
})

// ==================== Methods ====================

/**
 * WebSocket 消息处理器
 */
function handleWebSocketMessage(data) {
  console.log('收到 WebSocket 消息:', data)
  
  switch (data.type) {
    case 'connected':
      wsConnected.value = true
      ElMessage.success('WebSocket连接成功')
      break
    
    case 'disconnected':
      wsConnected.value = false
      ElMessage.warning('WebSocket连接断开')
      break
    
    case 'init':
      // ✅ WebSocket初始化消息包含在线客户端，但我们已经有完整列表了
      // 只需要更新已有的在线客户端状态，不要覆盖离线客户端
      console.log('WebSocket初始化客户端列表:', data)
      if (data.clients && Array.isArray(data.clients)) {
        // 合并更新：更新已存在的客户端，添加新的在线客户端（但保留离线客户端）
        data.clients.forEach(wsClient => {
          // ✅ 确保客户端对象有效
          if (!wsClient || typeof wsClient !== 'object') {
            console.warn('[WebSocket] 跳过无效的客户端数据:', wsClient)
            return
          }
          
          const existingIndex = clientList.value.findIndex(c => c && c.client_id === wsClient.client_id)
          // ✅ 更新时确保所有必需字段都有默认值
          const updatedClient = {
            ...wsClient,
            client_name: wsClient.client_name || wsClient.hostname || wsClient.client_id || '未知客户端',
            client_id: wsClient.client_id || wsClient.id || '',
            hostname: wsClient.hostname || '',
            ip_address: wsClient.ip_address || '',
            client_type: wsClient.client_type || '',  // ✅ 保留账号类型
            online_status: wsClient.online_status || 'offline',
            browser_status: wsClient.browser_status || 'stopped',
            login_status: wsClient.login_status || 'not_logged_in',
            work_status: wsClient.work_status || 'idle',
            online_status_cn: wsClient.online_status === 'online' ? '在线' : '离线',
            browser_status_cn: getBrowserStatusLabel(wsClient.browser_status),
            login_status_cn: getLoginStatusLabel(wsClient.login_status),
            work_status_cn: getWorkStatusLabel(wsClient.work_status || 'idle')
          }
          if (existingIndex > -1) {
            // 更新已存在的客户端（可能从离线变为在线）
            const existingClient = clientList.value[existingIndex]
            Object.assign(clientList.value[existingIndex], {
              ...updatedClient,
              // ✅ 保留账号类型（WebSocket更新不应覆盖账号类型）
              client_type: existingClient.client_type || updatedClient.client_type || ''
            })
          } else {
            // 新的在线客户端（之前数据库中没有）
            clientList.value.push(updatedClient)
          }
        })
        agentStore.setClients(clientList.value)
      }
      break
    
    case 'client_update':
      console.log('客户端更新:', data)
      if (data.client) {
        updateClientInList(data.client)
      }
      break
      
    case 'status_update':
      // status_update消息格式：{ client_id, data: { work_status, browser_status, ... } }
      console.log('状态更新:', data)
      if (data.client_id && data.data) {
        // 从客户端列表中找到对应客户端并更新状态
        const index = clientList.value.findIndex(c => c && c.client_id === data.client_id)
        if (index > -1) {
          // ✅ 更新状态数据（保留原有数据，只更新状态相关字段）
          const existingClient = clientList.value[index]
          if (existingClient) {
            // ✅ 处理 online (bool) 和 online_status (str) 两种格式
            let onlineStatus = existingClient.online_status || 'offline'
            if (data.data.online_status) {
              onlineStatus = data.data.online_status
            } else if ('online' in data.data) {
              // 兼容 Agent 发送的 online (bool) 格式
              onlineStatus = data.data.online ? 'online' : 'offline'
            }
            
            Object.assign(clientList.value[index], {
              ...data.data,
              // ✅ 确保 client_name 等必需字段存在
              client_name: existingClient.client_name || data.data.client_name || existingClient.hostname || existingClient.client_id || '未知客户端',
              client_id: existingClient.client_id || data.data.client_id || '',
              hostname: existingClient.hostname || data.data.hostname || '',
              ip_address: existingClient.ip_address || data.data.ip_address || '',
              // ✅ 保留账号类型（状态更新不应覆盖账号类型）
              client_type: existingClient.client_type || data.data.client_type || '',
              // ✅ 确保 online_status 字段存在（兼容两种格式）
              online_status: onlineStatus,
              // 同步更新中文状态
              work_status_cn: getWorkStatusLabel(data.data.work_status || existingClient.work_status || 'idle'),
              browser_status_cn: getBrowserStatusLabel(data.data.browser_status || existingClient.browser_status),
              login_status_cn: getLoginStatusLabel(data.data.login_status || existingClient.login_status),
              online_status_cn: onlineStatus === 'online' ? '在线' : '离线',
              // 保留原有数据（避免覆盖）
              default_address_info: existingClient.default_address_info,
              cookies: existingClient.cookies
            })
            
            // ✅ 如果状态变为已登录，关闭所有登录弹窗
            const newLoginStatus = data.data.login_status || existingClient.login_status
            if (newLoginStatus === 'logged_in') {
              if (qrLoginVisible.value && currentQRClient.value?.client_id === data.client_id) {
                qrLoginVisible.value = false
                stopQRCountdown()
              }
              if (smsLoginVisible.value && currentSMSClient.value?.client_id === data.client_id) {
                smsLoginVisible.value = false
              }
            }
            
            // 如果详情弹窗打开且是当前客户端，同步更新详情数据
            if (detailDialogVisible.value && detailData.client_id === data.client_id) {
              Object.assign(detailData, {
                ...data.data,
                // ✅ 保留账号类型（状态更新不应覆盖账号类型）
                client_type: detailData.client_type || data.data.client_type || '',
                work_status_cn: getWorkStatusLabel(data.data.work_status || detailData.work_status || 'idle'),
                browser_status_cn: getBrowserStatusLabel(data.data.browser_status || detailData.browser_status),
                login_status_cn: getLoginStatusLabel(data.data.login_status || detailData.login_status),
                online_status_cn: (data.data.online_status || detailData.online_status) === 'online' ? '在线' : '离线'
              })
            }
          }
        }
      }
      break
    
    case 'client_disconnected':
      console.log('客户端断开:', data)
      const client = clientList.value.find(c => c && c.client_id === data.client_id)
      if (client) {
        client.online_status = 'offline'
        client.online_status_cn = '离线'
      }
      break
    
    case 'client_response':
      console.log('客户端响应:', data)
      handleClientResponse(data)
      break
  }
}

/**
 * 更新客户端列表中的单个客户端
 */
function updateClientInList(client) {
  // ✅ 确保客户端对象有效
  if (!client || typeof client !== 'object') {
    console.warn('[updateClientInList] 跳过无效的客户端数据:', client)
    return
  }
  
  const index = clientList.value.findIndex(c => c && c.client_id === client.client_id)
  // ✅ 更新时确保所有必需字段都有默认值，防止 undefined 错误
  const updatedClient = {
    ...client,
    client_name: client.client_name || client.hostname || client.client_id || '未知客户端',
    client_id: client.client_id || client.id || '',
    hostname: client.hostname || '',
    ip_address: client.ip_address || '',
    client_type: client.client_type || '',  // ✅ 保留账号类型
    online_status: client.online_status || 'offline',
    browser_status: client.browser_status || 'stopped',
    login_status: client.login_status || 'not_logged_in',
    work_status: client.work_status || 'idle',
    online_status_cn: client.online_status === 'online' ? '在线' : '离线',
    browser_status_cn: getBrowserStatusLabel(client.browser_status),
    login_status_cn: getLoginStatusLabel(client.login_status),
    work_status_cn: getWorkStatusLabel(client.work_status || 'idle')
  }
  
  if (index > -1) {
    // 保留原有的地址信息和其他数据
    const existingClient = clientList.value[index]
    if (existingClient) {
      Object.assign(clientList.value[index], {
        ...updatedClient,
        // ✅ 保留账号类型（状态更新不应覆盖账号类型）
        client_type: existingClient.client_type || updatedClient.client_type || '',
        // 保留原有地址信息（如果新数据没有）
        default_address_info: updatedClient.default_address_info || existingClient.default_address_info,
        // 保留cookies（如果新数据没有）
        cookies: updatedClient.cookies || existingClient.cookies
      })
    }
  } else {
    clientList.value.push(updatedClient)
  }
  agentStore.updateClient(updatedClient)
  
  // 如果详情弹窗打开且是当前客户端，同步更新详情数据
  if (detailDialogVisible.value && detailData.client_id === client.client_id) {
    Object.assign(detailData, {
      ...updatedClient,
      // ✅ 保留账号类型（客户端更新不应覆盖账号类型）
      client_type: detailData.client_type || updatedClient.client_type || '',
      // 保留地址信息
      default_address_info: updatedClient.default_address_info || detailData.default_address_info,
      // 保留cookies
      cookies: updatedClient.cookies || detailData.cookies
    })
  }
}

/**
 * 处理客户端响应
 */
function handleClientResponse(data) {
  const { event, message, client_id } = data

  if (event === 'login' && message.event === 'login') {
    if (message.data && message.data.qrcode) {
      // 二维码数据 - 转换为data URI格式
      qrCodeData.value = `data:image/png;base64,${message.data.qrcode}`
      qrLoading.value = false
      qrStatusText.value = '请使用闲鱼APP扫描二维码'
    } else if (message.data && message.data.type === 'qrcode_status') {
      // 二维码状态更新 - 显示在二维码下方，不弹窗
      const statusMap = {
        'NEW': '等待扫码',
        'SCANED': '✅ 已扫描，等待确认',
        'CONFIRMED': '✅ 已确认，处理中...'
      }
      qrStatusText.value = statusMap[message.data.status] || message.msg
    } else if (message.data && message.data.type === 'face_verification') {
      // 需要人脸识别 - 替换二维码，更新状态文本
      qrCodeData.value = `data:image/png;base64,${message.data.qrcode}`
      qrStatusText.value = '⚠️ 需要人脸识别，请使用闲鱼APP扫描此二维码'
      // 只弹一次提示
      ElMessage.warning({
        message: '检测到需要人脸识别验证',
        duration: 3000
      })
    } else if (message.data && message.data.type === 'already_logged') {
      // 账号已经登录，无需再次登录
      ElMessage.info({
        message: `账号已登录: ${message.data.account}`,
        duration: 2000
      })
      // 关闭所有登录弹窗
      qrLoginVisible.value = false
      smsLoginVisible.value = false
      // 停止倒计时和重置状态
      stopQRCountdown()
      qrStatusText.value = '请使用闲鱼APP扫描二维码'
    } else if (message.success && message.data && message.data.logged_in) {
      // ✅ 登录成功（通过logged_in标志判断）
      ElMessage.success('登录成功')
      qrLoginVisible.value = false
      smsLoginVisible.value = false
      // 停止倒计时和重置状态
      stopQRCountdown()
      qrStatusText.value = '请使用闲鱼APP扫描二维码'
    } else if (message.success) {
      // 检查是否是短信验证码发送成功（需要等待输入验证码）
      if (message.data && message.data.wait_code) {
        // 验证码已发送，保持弹窗打开，等待用户输入
        ElMessage.success(message.msg || '验证码已发送')
        // 不关闭 smsLoginVisible，让用户输入验证码
      } else {
        // 真正的登录成功
        ElMessage.success('登录成功')
        qrLoginVisible.value = false
        smsLoginVisible.value = false
        // 停止倒计时和重置状态
        stopQRCountdown()
        qrStatusText.value = '请使用闲鱼APP扫描二维码'
      }
    } else {
      // 登录失败
      ElMessage.error(message.msg || '登录失败')
    }
  } else if (event === 'get_address' && message.event === 'get_address') {
    // 地址列表响应
    console.log('📝 收到get_address响应:', message)
    console.log('📝 message.data:', message.data)
    console.log('📝 message.success:', message.success)
    // ⚠️ 注意：message本身包含success、data等字段
    handleAddressListResponse(message)
  }
}

/**
 * 从HTTP API加载完整客户端列表（包括离线）
 */
async function loadClientListFromAPI() {
  try {
    // 构建查询参数，过滤掉空字符串（确保离线主机也能显示）
    // ✅ 重要：如果不传递 online_status 参数，后端会返回所有客户端（包括离线）
    // 这样即使 agent 未启动，数据库中已注册的主机也能显示为"离线"状态
    const apiParams = {
      page_num: 1,
      page_size: 1000 // 获取足够多的记录以显示所有客户端
    }
    // 只添加非空的查询参数（空字符串不添加，确保离线主机也能显示）
    // ⚠️ 注意：queryParams 是用 reactive 创建的，不需要 .value（这是 Vue 3 的规则）
    if (queryParams.client_name) apiParams.client_name = queryParams.client_name
    if (queryParams.ip_address) apiParams.ip_address = queryParams.ip_address
    // 如果 online_status 为空字符串，不添加此参数，后端返回所有客户端
    if (queryParams.online_status) apiParams.online_status = queryParams.online_status
    if (queryParams.login_status) apiParams.login_status = queryParams.login_status
    if (queryParams.browser_status) apiParams.browser_status = queryParams.browser_status
    
    const res = await getAgentClientList(apiParams)
    
    // ✅ 确保 res 存在
    if (!res) {
      console.warn('[ClientList] API返回为空，设置空列表')
      clientList.value = []
      agentStore.setClients([])
      return
    }
    
    // ✅ 修复：API可能直接返回rows，也可能在data.rows中（根据响应拦截器的处理）
    // 如果 res.code 存在且为 200，或者 res.success 为 true，都认为是成功
    if ((res.code === 200 || res.success === true) && res) {
      // ✅ 安全获取客户端列表数据
      let clients = []
      
      // 优先检查直接返回的rows（某些接口响应拦截器可能没有包装）
      if (res.rows && Array.isArray(res.rows)) {
        clients = res.rows
      } else if (res.data && Array.isArray(res.data)) {
        // 响应拦截器已处理，data是数组
        clients = res.data
      } else if (res.data && res.data.rows && Array.isArray(res.data.rows)) {
        // 响应拦截器已处理，data.rows是数组
        clients = res.data.rows
      } else if (res.data && res.data.list && Array.isArray(res.data.list)) {
        // 响应拦截器已处理，data.list是数组
        clients = res.data.list
      } else {
        console.warn('[ClientList] API返回的数据格式异常:', res)
        clients = []
      }
      
      // ✅ 加强数据验证：过滤掉所有无效项
      const validClients = []
      for (let i = 0; i < clients.length; i++) {
        const client = clients[i]
        
        // 严格验证：必须是有效的对象
        if (!client || typeof client !== 'object' || Array.isArray(client)) {
          console.warn(`[ClientList] 跳过无效的客户端数据项 [${i}]:`, client)
          continue
        }
        
        // ✅ 确保所有必需字段都有默认值，防止 undefined 错误
        try {
          validClients.push({
            ...client,
            client_name: (client && typeof client === 'object' && client.client_name) || client?.hostname || client?.client_id || '未知客户端',
            client_id: (client && typeof client === 'object' && client.client_id) || client?.id || '',
            hostname: (client && typeof client === 'object' && client.hostname) || '',
            ip_address: (client && typeof client === 'object' && client.ip_address) || '',
            client_type: (client && typeof client === 'object' && client.client_type) || '',  // ✅ 保留账号类型
            online_status: (client && typeof client === 'object' && client.online_status) || 'offline',
            browser_status: (client && typeof client === 'object' && client.browser_status) || 'stopped',
            login_status: (client && typeof client === 'object' && client.login_status) || 'not_logged_in',
            work_status: (client && typeof client === 'object' && client.work_status) || 'idle',
            online_status_cn: (client && typeof client === 'object' && client.online_status) === 'online' ? '在线' : '离线',
            browser_status_cn: getBrowserStatusLabel((client && typeof client === 'object' && client.browser_status) || 'stopped'),
            login_status_cn: getLoginStatusLabel((client && typeof client === 'object' && client.login_status) || 'not_logged_in'),
            work_status_cn: getWorkStatusLabel((client && typeof client === 'object' && client.work_status) || 'idle')
          })
        } catch (error) {
          console.error(`[ClientList] 处理客户端数据项 [${i}] 时出错:`, error, client)
          // 跳过这个项，继续处理下一个
          continue
        }
      }
      
      clientList.value = validClients
      
      agentStore.setClients(clientList.value)
      console.log(`[ClientList] 从API加载了 ${clientList.value.length} 个客户端（包括离线）`)
    } else {
      // ✅ 即使返回的数据格式不符合预期，也设置空列表，避免undefined错误
      console.warn('[ClientList] API返回的数据不符合预期:', res)
      clientList.value = []
      agentStore.setClients([])
      
      // 只有在确实失败时才显示错误（避免"操作成功"的误报）
      if (res && res.code && res.code !== 200 && res.msg && res.msg !== '操作成功') {
      ElMessage.error(res.msg || '加载客户端列表失败')
      }
    }
  } catch (error) {
    console.error('加载客户端列表失败:', error)
    // ✅ 确保即使出错，也设置空列表，避免undefined错误
    clientList.value = []
    agentStore.setClients([])
    
    // 避免显示"操作成功"的错误提示
    if (error !== 'error' && error.message && error.message !== '操作成功') {
    ElMessage.error('加载客户端列表失败: ' + (error.message || '未知错误'))
    }
  }
}

/**
 * 刷新客户端列表（从HTTP API重新加载）
 */
async function loadClientList() {
  try {
    await loadClientListFromAPI()
    ElMessage.success('客户端列表已刷新')
  } catch (error) {
    // 错误已在loadClientListFromAPI中处理，这里不重复提示
  }
}

/**
 * 搜索
 */
function handleQuery() {
  // 过滤由computed自动处理
}

/**
 * 重置搜索
 */
function resetQuery() {
  queryRef.value?.resetFields()
}

/**
 * 导出
 */
function handleExport() {
  ElMessage.info('导出功能开发中...')
}

/**
 * 检查Agent操作权限（管理员警告，非管理员拒绝）
 * @returns {boolean} true=允许操作, false=拒绝操作
 */
function checkAgentOperationPermission(row, operationName = '操作') {
  const userStore = useUserStore()
  const currentUserId = userStore.id  // 修复：使用 id 而不是 userId
  
  // 调试日志
  console.log(`[权限检查] Agent: ${row.client_name}, assigned_user_id: ${row.assigned_user_id} (${typeof row.assigned_user_id}), currentUserId: ${currentUserId} (${typeof currentUserId}), isAdmin: ${isAdmin.value}`)
  
  // 如果Agent未分配给任何人，允许操作
  if (!row.assigned_user_id) {
    console.log('[权限检查] ✅ Agent未分配，允许操作')
    return true
  }
  
  // 如果是分配给自己的Agent，允许操作（转换为字符串比较）
  if (String(row.assigned_user_id) === String(currentUserId)) {
    console.log('[权限检查] ✅ Agent分配给当前用户，允许操作')
    return true
  }
  
  // 非管理员，且Agent分配给其他用户，拒绝操作
  if (!isAdmin.value) {
    console.log('[权限检查] ❌ 非管理员且Agent分配给其他用户，拒绝操作')
    ElMessage.error(`无权${operationName}此Agent（仅能操作分配给自己的Agent）`)
    return false
  }
  
  // 管理员，但Agent分配给其他用户，仅警告（允许操作）
  console.log('[权限检查] ⚠️ 管理员操作其他用户的Agent，警告')
  ElMessage.warning(`⚠️ 此Agent已分配给其他用户（User ID: ${row.assigned_user_id}），请谨慎操作`)
  return true
}

/**
 * 启动浏览器
 */
function handleStart(row) {
  if (!checkAgentOperationPermission(row, '启动')) {
    return
  }
  
  websocketManager.send({
    event: 'start',
    direction: 'req',
    data: {
      client_id: row.client_id
    }
  })
  ElMessage.success('已发送启动命令')
}

/**
 * 关闭浏览器
 */
function handleStop(row) {
  if (!checkAgentOperationPermission(row, '停止')) {
    return
  }
  
  websocketManager.send({
    event: 'stop',
    direction: 'req',
    data: {
      client_id: row.client_id
    }
  })
  ElMessage.success('已发送关闭命令')
}

/**
 * 重置浏览器（删除所有user_data，全新登录）
 */
function handleReset(row) {
  // ✅ 权限检查
  if (!checkAgentOperationPermission(row, '重置')) {
    return
  }
  
  // 二次确认
  ElMessageBox.confirm(
    '⚠️ 重置浏览器将删除所有浏览器数据（Cookie、缓存、登录状态），需要重新登录。是否继续？',
    '确认重置',
    {
      confirmButtonText: '确认重置',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(() => {
    websocketManager.send({
      event: 'reset',
      direction: 'req',
      data: {
        client_id: row.client_id
      }
    })
    ElMessage.success('已发送重置命令')
  }).catch(() => {
    ElMessage.info('已取消重置')
  })
}


/**
 * 格式化倒计时（10:00）
 */
function formatCountdown(seconds) {
  const minutes = Math.floor(seconds / 60)
  const secs = seconds % 60
  return `${minutes}:${secs.toString().padStart(2, '0')}`
}

/**
 * 启动倒计时
 */
function startQRCountdown() {
  // 清除旧定时器
  if (qrCountdownTimer.value) {
    clearInterval(qrCountdownTimer.value)
  }
  
  // 重置倒计时（10分钟）
  qrCountdown.value = 600
  qrExpireTime.value = Date.now() + 600000
  
  // 每秒更新倒计时
  qrCountdownTimer.value = setInterval(() => {
    qrCountdown.value--
    if (qrCountdown.value <= 0) {
      clearInterval(qrCountdownTimer.value)
      qrCountdownTimer.value = null
    }
  }, 1000)
}

/**
 * 停止倒计时
 */
function stopQRCountdown() {
  if (qrCountdownTimer.value) {
    clearInterval(qrCountdownTimer.value)
    qrCountdownTimer.value = null
  }
  qrCountdown.value = 600
}

/**
 * 二维码登录
 */
function handleQRLogin(row) {
  // ✅ 检查登录状态，避免已登录状态下触发登录流程
  if (row.login_status === 'logged_in') {
    ElMessage.warning('该账号已登录，无需重复登录')
    return
  }
  
  // ✅ 检查是否在线
  if (row.online_status !== 'online') {
    ElMessage.warning('客户端未在线，无法进行登录')
    return
  }
  
  currentQRClient.value = row
  qrCodeData.value = ''
  qrLoginVisible.value = true
  qrLoading.value = true
  qrStatusText.value = '正在获取二维码...'
  
  // 启动倒计时
  startQRCountdown()

  websocketManager.send({
    event: 'login',
    direction: 'req',
    data: {
      client_id: row.client_id,
      type: 'qrcode'
    }
  })
}

/**
 * 刷新二维码
 */
function handleRefreshQRCode() {
  if (!currentQRClient.value) {
    return
  }
  
  // ✅ 检查登录状态，避免已登录状态下刷新二维码
  if (currentQRClient.value.login_status === 'logged_in') {
    ElMessage.warning('该账号已登录，无需刷新二维码')
    qrLoginVisible.value = false
    return
  }
  
  qrCodeData.value = ''
  qrLoading.value = true
  // 重启倒计时
  startQRCountdown()
  
  websocketManager.send({
    event: 'login',
    direction: 'req',
    data: {
      client_id: currentQRClient.value.client_id,
      type: 'qrcode',
      refresh: true // 标记为刷新
    }
  })
}

/**
 * 手机号登录
 */
function handleSMSLogin(row) {
  // ✅ 检查登录状态，避免已登录状态下触发登录流程
  if (row.login_status === 'logged_in') {
    ElMessage.warning('该账号已登录，无需重复登录')
    return
  }
  
  // ✅ 检查是否在线
  if (row.online_status !== 'online') {
    ElMessage.warning('客户端未在线，无法进行登录')
    return
  }
  
  currentSMSClient.value = row
  smsForm.phone = ''
  smsForm.code = ''
  smsLoginVisible.value = true
}

/**
 * 发送短信验证码
 */
function handleSendSMS() {
  if (!smsForm.phone) {
    ElMessage.warning('请输入手机号')
    return
  }

  // 发送验证码请求（不包含code参数）
  websocketManager.send({
    event: 'login',
    direction: 'req',
    data: {
      client_id: currentSMSClient.value.client_id,
      type: 'sms',
      phone: smsForm.phone
      // 注意：没有code参数，Agent会识别为发送验证码
    }
  })

  // 开始倒计时
  smsCooldown.value = 60
  const timer = setInterval(() => {
    smsCooldown.value--
    if (smsCooldown.value <= 0) {
      clearInterval(timer)
    }
  }, 1000)
  
  // 不在这里显示成功消息，等Agent返回后再显示
}

/**
 * 提交手机号登录
 */
function handleSMSSubmit() {
  if (!smsForm.phone || !smsForm.code) {
    ElMessage.warning('请输入手机号和验证码')
    return
  }

  // 提交验证码登录（包含code参数）
  websocketManager.send({
    event: 'login',
    direction: 'req',
    data: {
      client_id: currentSMSClient.value.client_id,
      type: 'sms',
      phone: smsForm.phone,
      code: smsForm.code
      // 注意：包含code参数，Agent会识别为提交验证码登录
    }
  })
}

/**
 * 选择地址
 */
async function handleSelectAddress(row) {
  if (!websocketManager.isConnected()) {
    ElMessage.error('WebSocket未连接，请刷新页面')
    return
  }
  
  if (row.online_status !== 'online') {
    ElMessage.warning('主机已离线，无法执行远程操作')
    return
  }
  
  if (row.login_status !== 'logged_in') {
    ElMessage.warning('请先登录该客户端')
    return
  }
  
  try {
    // 保存当前客户端信息
    currentAddressClient.value = row
    
    // 显示弹窗和加载状态
    addressDialogVisible.value = true
    addressLoading.value = true
    addressList.value = []
    selectedAddressId.value = null
    
    // 发送获取地址列表命令
    const success = await websocketManager.send({
      event: 'get_address',
      direction: 'req',
      data: {
        client_id: row.client_id
      }
    })
    
    if (!success) {
      ElMessage.error('发送命令失败')
      addressLoading.value = false
      addressDialogVisible.value = false
      return
    }
    
  } catch (error) {
    console.error('选择地址失败:', error)
    ElMessage.error('选择地址失败: ' + error.message)
    addressLoading.value = false
    addressDialogVisible.value = false
  }
}

/**
 * 处理地址列表响应
 */
function handleAddressListResponse(response) {
  console.log('📝 处理地址列表响应:', response)
  
  addressLoading.value = false
  
  // ✅ response结构：{ success, code, msg, data: { addresses: [...], count: X } }
  if (response.success && response.data && response.data.addresses && Array.isArray(response.data.addresses)) {
    const addresses = response.data.addresses
    console.log('📝 解析到的地址列表:', addresses)
    console.log('📝 地址数量:', addresses.length)
    
    addressList.value = addresses
    
    // 优先选中客户端已保存的地址，如果没有则选中默认地址，最后才选中第一个
    if (currentAddressClient.value && currentAddressClient.value.default_address_id) {
      // 查找客户端已保存的地址
      const savedAddress = addresses.find(addr => addr.id === currentAddressClient.value.default_address_id)
      if (savedAddress) {
        selectedAddressId.value = savedAddress.id
      } else {
        // 如果保存的地址不在列表中，查找默认地址或第一个
    const defaultAddress = addresses.find(addr => addr.isDefault)
        selectedAddressId.value = defaultAddress ? defaultAddress.id : (addresses.length > 0 ? addresses[0].id : null)
      }
    } else {
      // 没有保存的地址，选中默认地址或第一个
      const defaultAddress = addresses.find(addr => addr.isDefault)
      selectedAddressId.value = defaultAddress ? defaultAddress.id : (addresses.length > 0 ? addresses[0].id : null)
    }
    
    if (addresses.length === 0) {
      ElMessage.warning('暂无收货地址，请先在闲鱼添加地址')
    } else {
      ElMessage.success(`获取到${addresses.length}个收货地址`)
    }
  } else {
    console.error('❌ 地址列表响应格式错误:', response)
    ElMessage.error(response.msg || '获取地址列表失败')
    addressDialogVisible.value = false
  }
}

/**
 * 确认选择地址
 */
async function handleConfirmAddress() {
  if (!selectedAddressId.value || !currentAddressClient.value) {
    return
  }
  
  try {
    const selectedAddress = addressList.value.find(addr => addr.id === selectedAddressId.value)
    if (!selectedAddress) {
      ElMessage.error('未找到选中的地址')
      return
    }
    
    // ✅ 准备地址详细信息（用于详情页直接显示）
    const addressInfo = {
      id: selectedAddress.id,
      name: selectedAddress.name,
      phone: selectedAddress.phone,
      fullAddress: selectedAddress.fullAddress, // 顶部灰色小字的完整地址
      addressDetail: selectedAddress.addressDetail || selectedAddress.detailAddress,
      isDefault: selectedAddress.isDefault
    }
    
    // ✅ 将地址ID和详细信息一起保存到数据库
    // default_address_id: 地址ID（用于下单）
    // default_address_info: 地址详细信息（JSON格式，用于详情页显示）
    await updateClient(currentAddressClient.value.id, {
      default_address_id: selectedAddressId.value,
      default_address_info: JSON.stringify(addressInfo)
    })
    
    // 保存到客户端数据中（用于详情页显示）
    currentAddressClient.value.default_address_id = selectedAddressId.value
    currentAddressClient.value.default_address_info = addressInfo
    
    // 同时更新列表中的该客户端数据
    const index = clientList.value.findIndex(c => c.client_id === currentAddressClient.value.client_id)
    if (index > -1) {
      clientList.value[index].default_address_id = selectedAddressId.value
      clientList.value[index].default_address_info = addressInfo
    }
    
    // ✅ 如果详情页已打开且是当前客户端，同步更新详情数据
    if (detailDialogVisible.value && detailData.client_id === currentAddressClient.value.client_id) {
      detailData.default_address_id = selectedAddressId.value
      detailData.default_address_info = addressInfo
    }
    
    ElMessage.success(`已选择地址：${selectedAddress.name} - ${selectedAddress.fullAddress}`)
    addressDialogVisible.value = false
    
  } catch (error) {
    console.error('保存地址失败:', error)
    ElMessage.error('保存地址失败: ' + error.message)
  }
}

/**
 * 关闭地址弹窗
 */
function handleAddressDialogClose() {
  addressList.value = []
  selectedAddressId.value = null
  currentAddressClient.value = null
  addressLoading.value = false
}

/**
 * 表格选择变化
 */
function handleSelectionChange(selection) {
  selectedClients.value = selection
}

/**
 * 获取账号用途标签类型
 */
function getClientTypeTagType(type) {
  const map = {
    'search': 'warning',   // 橙色 - 搜索
    'order': 'success',    // 绿色 - 下单
    'standby': ''          // 灰色 - 备用
  }
  return map[type] || 'info'
}

/**
 * 获取账号用途标签文本
 */
function getClientTypeLabel(type) {
  const map = {
    'search': '搜索',
    'order': '下单',
    'standby': '备用'
  }
  return map[type] || '未设置'
}

/**
 * 打开编辑弹窗
 */
/**
 * 查看主机详情
 */
async function handleViewDetail(row) {
  // 复制所有数据到 detailData
  Object.keys(detailData).forEach(key => {
    if (key === 'cookies') {
      // 保留cookies（可能是JSON字符串）
      detailData[key] = row[key] || null
    } else if (key === 'default_address_info') {
      // 优先使用row中保存的地址信息，如果没有则从客户端列表中查找
      detailData[key] = row[key] || (() => {
        // 从客户端列表中查找该客户端，看是否有保存的地址信息
        const clientInList = clientList.value.find(c => c.client_id === row.client_id)
        return clientInList?.default_address_info || null
      })()
    } else {
      detailData[key] = row[key] || ''
    }
  })
  
  // 如果没有地址信息但有地址ID，尝试从当前打开的地址弹窗中获取
  if (detailData.default_address_id && !detailData.default_address_info && addressList.value && addressList.value.length > 0) {
    const address = addressList.value.find(addr => addr.id === detailData.default_address_id)
    if (address) {
      detailData.default_address_info = {
        id: address.id,
        name: address.name,
        phone: address.phone,
        fullAddress: address.fullAddress,
        addressDetail: address.addressDetail || address.detailAddress,
        isDefault: address.isDefault
      }
    }
  }
  
  detailDialogVisible.value = true
}

/**
 * 格式化Cookie（用于详情页显示）
 */
function formatCookie(cookies) {
  if (!cookies) return '-'
  try {
    if (typeof cookies === 'string') {
      return JSON.stringify(JSON.parse(cookies), null, 2)
    } else {
      return JSON.stringify(cookies, null, 2)
    }
  } catch {
    return cookies
  }
}

/**
 * 获取Cookie数量
 */
function getCookieCount(cookies) {
  if (!cookies) return 0
  try {
    if (typeof cookies === 'string') {
      return Object.keys(JSON.parse(cookies)).length
    } else {
      return Object.keys(cookies).length
    }
  } catch {
    return 1
  }
}

/**
 * 获取关键Cookie信息（用于折叠状态下显示）
 */
function getKeyCookieInfo(cookies) {
  if (!cookies) return null
  
  try {
    let cookieObj = cookies
    if (typeof cookies === 'string') {
      cookieObj = JSON.parse(cookies)
    }
    
    // 只显示关键的Cookie字段
    const keyFields = ['_m_h5_tk', 'tracknick', 'unb', 'havana_1gc2_77', 'havana_lgc_exp']
    const result = {}
    
    keyFields.forEach(key => {
      if (cookieObj[key]) {
        let value = cookieObj[key]
        // 如果值太长，截断显示
        if (value.length > 50) {
          value = value.substring(0, 50) + '...'
        }
        result[key] = value
      }
    })
    
    return Object.keys(result).length > 0 ? result : null
  } catch {
    return null
  }
}

/**
 * 编辑Agent
 */
function handleEdit(row) {
  currentEditClient.value = row
  editForm.id = row.id
  editForm.client_type = row.client_type || 'search'
  editForm.remark = row.remark || ''
  editDialogVisible.value = true
}

/**
 * 保存编辑
 */
async function handleSaveEdit() {
  try {
    // 调用API更新Agent信息
    await updateClient(editForm.id, {
      client_type: editForm.client_type,
      remark: editForm.remark
    })
    
    // 更新本地数据
    if (currentEditClient.value) {
      currentEditClient.value.client_type = editForm.client_type
      currentEditClient.value.remark = editForm.remark
    }
    
    editDialogVisible.value = false
    ElMessage.success('保存成功')
  } catch (error) {
    console.error('保存失败:', error)
    ElMessage.error('保存失败: ' + error.message)
  }
}

/**
 * 获取浏览器状态标签类型
 */
function getBrowserStatusType(status) {
  const map = {
    'running': 'success',
    'stopped': 'info',
    'starting': 'warning',
    'error': 'danger'
  }
  return map[status] || 'info'
}

/**
 * 获取表格行的类名（用于设置离线主机的灰色背景）
 */
function getRowClassName({ row, rowIndex }) {
  // ✅ error和banned状态都使用红色背景
  if (row.work_status === 'error' || row.work_status === 'banned') {
    return 'row-error'
  }
  if (row.online_status === 'offline') {
    return 'row-offline'
  }
  return ''
}

/**
 * 获取浏览器状态中文标签
 */
function getBrowserStatusLabel(status) {
  const map = {
    'running': '运行中',
    'stopped': '已停止',
    'starting': '启动中',
    'error': '错误'
  }
  return map[status] || status || '-'
}

/**
 * 获取登录状态标签类型
 */
function getLoginStatusType(status) {
  const map = {
    'logged_in': 'success',
    'not_logged_in': 'info',
    'logging_in': 'warning',
    'login_error': 'danger',
    'qrcode_scanning': 'warning',
    'sms_waiting': 'warning'
  }
  return map[status] || 'info'
}

/**
 * 获取登录状态中文标签
 */
function getLoginStatusLabel(status) {
  const map = {
    'logged_in': '已登录',
    'not_logged_in': '未登录',
    'logging_in': '登录中',
    'login_error': '登录失败',
    'qrcode_scanning': '扫码中',
    'sms_waiting': '等待验证码'
  }
  return map[status] || status || '-'
}

/**
 * 获取工作状态标签类型
 */
function getWorkStatusType(status) {
  const map = {
    'idle': 'info',
    'searching': 'warning',
    'ordering': 'success',
    'risk_control': 'danger',
    'error': 'danger',
    'banned': 'danger'  // banned状态使用danger类型（红色）
  }
  return map[status] || 'info'
}

/**
 * 获取工作状态中文标签
 */
function getWorkStatusLabel(status) {
  const map = {
    'idle': '空闲中',
    'searching': '搜索中',
    'ordering': '下单中',
    'risk_control': '风控中',
    'error': '错误',
    'banned': '封禁中'
  }
  return map[status] || status || '空闲中'
}

/**
 * 获取地址显示信息（用于详情页 - 返回姓名和地址）
 */
function getAddressDisplayInfo(detailData) {
  if (!detailData.default_address_id) return null
  
  let addressInfo = null
  
  // ✅ 优先从数据库中保存的地址信息获取（JSON格式）
  if (detailData.default_address_info) {
    try {
      // 如果是字符串，解析为JSON对象
      if (typeof detailData.default_address_info === 'string') {
        addressInfo = JSON.parse(detailData.default_address_info)
      } else {
        // 如果已经是对象，直接使用
        addressInfo = detailData.default_address_info
      }
    } catch (e) {
      console.error('解析地址信息失败:', e)
      addressInfo = null
    }
  }
  
  // ✅ 降级：如果数据库没有，尝试从当前地址列表中获取
  if (!addressInfo && addressList.value && addressList.value.length > 0) {
    const address = addressList.value.find(addr => addr.id === detailData.default_address_id)
    if (address) {
      addressInfo = {
        name: address.name,
        fullAddress: address.fullAddress,
        addressDetail: address.addressDetail || address.detailAddress
      }
    }
  }
  
  if (!addressInfo) return null
  
  // 构建返回对象：姓名和完整地址
  const result = {
    name: addressInfo.name || '',
    address: ''
  }
  
  // 组合完整地址：优先使用 fullAddress + addressDetail，如果只有其中一个就只用那个
  const fullAddr = addressInfo.fullAddress || ''
  const detailAddr = addressInfo.addressDetail || addressInfo.detailAddress || ''
  
  if (fullAddr && detailAddr) {
    // 如果两者都有，组合起来
    result.address = `${fullAddr}${detailAddr}`
  } else {
    // 如果只有一个，直接用那个
    result.address = fullAddr || detailAddr
  }
  
  // 如果姓名和地址都有值，才返回
  if (result.name || result.address) {
    return result
  }
  
  return null
}

/**
 * 根据行数据获取地址显示文本（用于表格）
 * 优先从数据库保存的地址信息显示，降级显示ID
 */
function getAddressDisplayTextForRow(row) {
  if (!row.default_address_id) return '-'
  
  let addressInfo = null
  
  // ✅ 优先从数据库中保存的地址信息获取
  if (row.default_address_info) {
    try {
      if (typeof row.default_address_info === 'string') {
        addressInfo = JSON.parse(row.default_address_info)
      } else {
        addressInfo = row.default_address_info
      }
    } catch (e) {
      console.error('解析地址信息失败:', e)
    }
  }
  
  // ✅ 降级：从当前打开的地址弹窗中获取
  if (!addressInfo && addressList.value && addressList.value.length > 0 && currentAddressClient.value && currentAddressClient.value.client_id === row.client_id) {
    const address = addressList.value.find(addr => addr.id === row.default_address_id)
    if (address) {
      addressInfo = address
    }
  }
  
  // 如果有地址信息，显示简要信息（姓名 + 地址缩写）
  if (addressInfo) {
    const name = addressInfo.name || ''
    const fullAddress = addressInfo.fullAddress || ''
    const shortAddress = fullAddress ? fullAddress.substring(0, 15) + (fullAddress.length > 15 ? '...' : '') : ''
    return `${name} ${shortAddress}`.trim() || `ID: ${row.default_address_id}`
  }
  
  // 默认显示ID
  return `ID: ${row.default_address_id}`
}

/**
 * 格式化日期
 * 支持字符串日期和Unix时间戳（数字）
 */
function formatDate(dateStringOrTimestamp) {
  if (!dateStringOrTimestamp) return '-'
  
  let date
  // 如果是数字（Unix时间戳），转换为Date对象
  if (typeof dateStringOrTimestamp === 'number') {
    date = new Date(dateStringOrTimestamp * 1000) // 转换为毫秒
  } else {
    // 如果是字符串，尝试解析
    date = new Date(dateStringOrTimestamp)
  }
  
  // 检查日期是否有效
  if (isNaN(date.getTime())) {
    return '-'
  }
  
  // 格式化为 YYYY-MM-DD HH:mm:ss
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  const seconds = String(date.getSeconds()).padStart(2, '0')
  
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}

/**
 * 自然排序函数（用于主机名排序）
 * 实现 agent-1, agent-2, ..., agent-10, agent-11 的排序
 * 而不是字母排序 agent-1, agent-11, agent-2, ...
 */
function naturalSortByHostName(a, b) {
  const aName = a.server_host_name || ''
  const bName = b.server_host_name || ''
  
  // 如果有空值，将空值排到最后
  if (!aName && !bName) return 0
  if (!aName) return 1
  if (!bName) return -1
  
  // 使用正则表达式分割字符串和数字
  const regex = /(\d+)|(\D+)/g
  const aParts = aName.match(regex) || []
  const bParts = bName.match(regex) || []
  
  // 逐部分比较
  const minLength = Math.min(aParts.length, bParts.length)
  for (let i = 0; i < minLength; i++) {
    const aPart = aParts[i]
    const bPart = bParts[i]
    
    // 检查是否都是数字
    const aIsNum = /^\d+$/.test(aPart)
    const bIsNum = /^\d+$/.test(bPart)
    
    if (aIsNum && bIsNum) {
      // 两者都是数字，按数值比较
      const diff = parseInt(aPart, 10) - parseInt(bPart, 10)
      if (diff !== 0) return diff
    } else {
      // 至少有一个不是数字，按字符串比较
      const diff = aPart.localeCompare(bPart)
      if (diff !== 0) return diff
    }
  }
  
  // 如果前面部分都相同，比较长度
  return aParts.length - bParts.length
}

// ==================== Agent分配功能函数 ====================

/**
 * 检查当前用户是否是管理员
 * 从Pinia store中获取用户信息
 */
function checkIsAdmin() {
  try {
    const userStore = useUserStore()
    
    // 从store获取权限和角色
    const permissions = userStore.permissions || []
    const roles = userStore.roles || []
    
    console.log('[Agent分配] Store权限:', permissions)
    console.log('[Agent分配] Store角色:', roles)
    
    // 方式1：检查permissions中是否有 *:*:*（超级管理员标识）
    if (permissions.includes('*:*:*')) {
      isAdmin.value = true
      console.log('[Agent分配] ✅ 通过*:*:*判断为超级管理员')
      return
    }
    
    // 方式2：检查roles中是否有admin角色
    const isAdminRole = roles.some(role => {
      // role可能是字符串"admin"或对象{roleKey: "admin"}
      if (typeof role === 'string') {
        return role === 'admin'
      }
      return role.roleKey === 'admin' || role.role_key === 'admin'
    })
    
    if (isAdminRole) {
      isAdmin.value = true
      console.log('[Agent分配] ✅ 通过角色判断为超级管理员')
      return
    }
    
    isAdmin.value = false
    console.log('[Agent分配] ❌ 当前用户不是管理员')
  } catch (error) {
    console.error('[Agent分配] ❌ 检查管理员权限失败:', error)
    isAdmin.value = false
  }
}

/**
 * 批量分配Agent
 */
async function handleBatchAssign() {
  if (selectedClients.value.length === 0) {
    ElMessage.warning('请先选择要分配的Agent')
    return
  }
  
  try {
    // 加载用户列表
    assignLoading.value = true
    const response = await listUser({
      pageNum: 1,
      pageSize: 1000 // 获取所有用户
    })
    
    userList.value = response.rows || []
    console.log('[Agent分配] 加载用户列表成功:', userList.value.length)
    console.log('[Agent分配] 第一个用户数据:', userList.value[0])
    
    // 重置表单
    assignForm.user_id = null
    
    // 打开对话框
    assignDialogVisible.value = true
  } catch (error) {
    console.error('[Agent分配] 加载用户列表失败:', error)
    ElMessage.error('加载用户列表失败：' + (error.message || '未知错误'))
  } finally {
    assignLoading.value = false
  }
}

/**
 * 提交Agent分配
 */
async function submitAssign() {
  try {
    assignLoading.value = true
    
    // 获取选中的agent ID列表
    const clientIds = selectedClients.value.map(c => c.id)
    
    // 调用API分配（1对1分配：单个user_id）
    await assignAgents({
      client_ids: clientIds,
      user_id: assignForm.user_id || null  // ✅ 改为单个user_id
    })
    
    ElMessage.success('分配成功')
    assignDialogVisible.value = false
    
    // 刷新列表
    await loadClientListFromAPI()
    
    // 清空选中
    selectedClients.value = []
  } catch (error) {
    console.error('[Agent分配] 分配失败:', error)
    ElMessage.error('分配失败：' + (error.message || '未知错误'))
  } finally {
    assignLoading.value = false
  }
}
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.mb-4 {
  margin-bottom: 16px;
}

/* ========== 地址卡片样式（参考C#设计） ========== */

/* 地址网格布局 - 3列 */
.address-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  padding: 4px;
}

/* 地址卡片 */
.address-card {
  position: relative;
  padding: 16px;
  border: 2px solid #d1d9e0;
  border-radius: 12px;
  cursor: pointer;
  transition: all 0.3s ease;
  background-color: #fff;
  min-height: 140px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* 卡片悬停效果 */
.address-card:hover {
  border-color: #f58300;
  box-shadow: 0 2px 12px rgba(245, 131, 0, 0.15);
  transform: translateY(-2px);
}

/* 选中的地址卡片 */
.address-card-selected {
  border-color: #67C23A !important;
  border-width: 3px !important;
  background: linear-gradient(135deg, #f0f9ff 0%, #e8f8f5 100%);
  box-shadow: 0 4px 20px rgba(103, 194, 58, 0.35);
  transform: translateY(-2px);
}

.address-card-selected:hover {
  border-color: #67C23A !important;
  box-shadow: 0 6px 24px rgba(103, 194, 58, 0.45);
}

/* 标签区域（右上角） */
.address-badges {
  position: absolute;
  top: 12px;
  right: 12px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  z-index: 1;
}

/* 默认地址徽章（闲鱼的默认地址） */
.address-default-badge {
  background: linear-gradient(135deg, #f58300 0%, #ff9933 100%);
  color: #fff;
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
  box-shadow: 0 2px 4px rgba(245, 131, 0, 0.3);
  white-space: nowrap;
}

/* 当前选中标签（后台选中的地址，显示在右上角） */
.address-selected-badge {
  background: linear-gradient(135deg, #67C23A 0%, #85ce61 100%);
  color: #fff;
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
  box-shadow: 0 2px 6px rgba(103, 194, 58, 0.4);
  white-space: nowrap;
  animation: selectedBounce 0.4s ease;
}

@keyframes selectedBounce {
  0% {
    transform: scale(0) rotate(-12deg);
    opacity: 0;
  }
  60% {
    transform: scale(1.1) rotate(5deg);
  }
  100% {
    transform: scale(1) rotate(0deg);
    opacity: 1;
  }
}

/* 顶部：省/市/区/街道 */
.address-top {
  font-size: 13px;
  color: #909399;
  line-height: 1.5;
  padding-right: 50px; /* 给默认标签留空间 */
}

/* 中间：详细地址（粗体加大） */
.address-middle {
  font-size: 15px;
  font-weight: 600;
  color: #303133;
  line-height: 1.6;
  min-height: 48px;
  flex: 1; /* 占据剩余空间 */
  display: -webkit-box;
  -webkit-line-clamp: 2; /* 最多显示2行 */
  line-clamp: 2; /* 标准属性，兼容性更好 */
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-all;
}

/* 底部：姓名 + 手机号 */
.address-bottom {
  font-size: 13px;
  color: #606266;
  display: flex;
  align-items: center;
  gap: 16px;
  padding-top: 8px;
  border-top: 1px solid #f0f0f0;
}

.address-name {
  font-weight: 500;
  color: #303133;
}

.address-phone {
  color: #909399;
}

/* 选中图标 */
.address-check-icon {
  position: absolute;
  bottom: 12px;
  right: 12px;
  animation: checkIn 0.3s ease;
}

@keyframes checkIn {
  from {
    transform: scale(0);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

/* 响应式：小屏幕2列 */
@media (max-width: 1200px) {
  .address-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* error和banned状态行背景色（浅红色） */
:deep(.el-table__body-wrapper .row-error) {
  background-color: #fce8e8 !important;  /* 异常/封禁背景色（浅红色，稍深） */
}

:deep(.el-table__body-wrapper .row-error:hover) {
  background-color: #fad4d4 !important;  /* 悬停时稍深的浅红色 */
}

:deep(.el-table__body-wrapper .row-error td) {
  background-color: #fce8e8 !important;  /* 异常/封禁背景色（浅红色，稍深） */
}

:deep(.el-table__body-wrapper .row-error:hover td) {
  background-color: #fad4d4 !important;  /* 悬停时稍深的浅红色 */
}

:deep(.row-offline) {
  background-color: #f5f5f5 !important;
}

:deep(.row-offline:hover) {
  background-color: #e8e8e8 !important;
}

/* 响应式：更小屏幕1列 */
@media (max-width: 768px) {
  .address-grid {
    grid-template-columns: 1fr;
  }
}
</style>
